From 7f5a3ba9a6c5cba5a6c0f02e6c517f49a3a975b2 Mon Sep 17 00:00:00 2001 From: "jfisch@us.ibm.com" Date: Tue, 23 Aug 2005 02:10:59 +0100 Subject: [PATCH] Add xenversion support --- tools/xenstat/libxenstat/src/xen-interface.c | 74 ++++++++++++++++++-- tools/xenstat/libxenstat/src/xen-interface.h | 4 ++ tools/xenstat/libxenstat/src/xenstat.c | 26 ++++++- tools/xenstat/libxenstat/src/xenstat.h | 2 + 4 files changed, 96 insertions(+), 10 deletions(-) diff --git a/tools/xenstat/libxenstat/src/xen-interface.c b/tools/xenstat/libxenstat/src/xen-interface.c index 9629237fc6..876560fd1e 100644 --- a/tools/xenstat/libxenstat/src/xen-interface.c +++ b/tools/xenstat/libxenstat/src/xen-interface.c @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include "version.h" #include "privcmd.h" #include "xen.h" @@ -56,24 +58,69 @@ void xi_uninit(xi_handle *handle) free (handle); } -/* Make Xen hypervisor call */ -int xi_make_dom0_op(xi_handle *handle, dom0_op_t *op, int opcode) +/* Make simple xen version hypervisor calls */ +static int xi_make_xen_version_hypercall(xi_handle *handle, long *vnum, xen_extraversion_t *ver) +{ + privcmd_hypercall_t privcmd; + multicall_entry_t multicall[2]; + int ret = 0; + + /* set up for doing hypercall */ + privcmd.op = __HYPERVISOR_multicall; + privcmd.arg[0] = (unsigned long)multicall; + privcmd.arg[1] = 2; + + /* first one to get xen version number */ + multicall[0].op = __HYPERVISOR_xen_version; + multicall[0].args[0] = (unsigned long)XENVER_version; + + /* second to get xen version flag */ + multicall[1].op = __HYPERVISOR_xen_version; + multicall[1].args[0] = (unsigned long)XENVER_extraversion; + multicall[1].args[1] = (unsigned long)ver; + + if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) { + perror("Failed to mlock privcmd structure"); + return -1; + } + + if (mlock( multicall, sizeof(multicall_entry_t)) < 0) { + perror("Failed to mlock multicall_entry structure"); + munlock( &multicall, sizeof(multicall_entry_t)); + return -1; + } + + if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) { + perror("Hypercall failed"); + ret = -1; + } + + *vnum = multicall[0].result; + + munlock( &privcmd, sizeof(privcmd_hypercall_t)); + munlock( &multicall, sizeof(multicall_entry_t)); + + return ret; +} + +/* Make Xen Dom0 op hypervisor call */ +static int xi_make_dom0_op(xi_handle *handle, dom0_op_t *dom_op, int dom_opcode) { privcmd_hypercall_t privcmd; int ret = 0; /* set up for doing hypercall */ privcmd.op = __HYPERVISOR_dom0_op; - privcmd.arg[0] = (unsigned long)op; - op->cmd = opcode; - op->interface_version = DOM0_INTERFACE_VERSION; + privcmd.arg[0] = (unsigned long)dom_op; + dom_op->cmd = dom_opcode; + dom_op->interface_version = DOM0_INTERFACE_VERSION; if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) { perror("Failed to mlock privcmd structure"); return -1; } - if (mlock( op, sizeof(dom0_op_t)) < 0) { + if (mlock( dom_op, sizeof(dom0_op_t)) < 0) { perror("Failed to mlock dom0_op structure"); munlock( &privcmd, sizeof(privcmd_hypercall_t)); return -1; @@ -85,7 +132,7 @@ int xi_make_dom0_op(xi_handle *handle, dom0_op_t *op, int opcode) } munlock( &privcmd, sizeof(privcmd_hypercall_t)); - munlock( op, sizeof(dom0_op_t)); + munlock( dom_op, sizeof(dom0_op_t)); return ret; } @@ -142,3 +189,16 @@ long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain, return op.u.getvcpucontext.cpu_time; } + +/* gets xen version information from hypervisor */ +int xi_get_xen_version(xi_handle *handle, long *vnum, xen_extraversion_t *ver) +{ + + /* gets the XENVER_version and XENVER_extraversion */ + if (xi_make_xen_version_hypercall( handle, vnum, ver) < 0) {; + perror("XEN VERSION Hypercall failed"); + return -1; + } + + return 0; +} diff --git a/tools/xenstat/libxenstat/src/xen-interface.h b/tools/xenstat/libxenstat/src/xen-interface.h index 45f882ce49..c60655a378 100644 --- a/tools/xenstat/libxenstat/src/xen-interface.h +++ b/tools/xenstat/libxenstat/src/xen-interface.h @@ -27,6 +27,7 @@ typedef uint32_t u32; typedef uint64_t u64; #include "dom0_ops.h" +#include "version.h" /* Opaque handles */ typedef struct xi_handle xi_handle; @@ -38,6 +39,9 @@ xi_handle *xi_init(); /* Release the handle to libxc, free resources, etc. */ void xi_uninit(xi_handle *handle); +/* Obtain xen version information from hypervisor */ +int xi_get_xen_version(xi_handle *, long *vnum, xen_extraversion_t *ver); + /* Obtain physinfo data from dom0 */ int xi_get_physinfo(xi_handle *, dom0_physinfo_t *); diff --git a/tools/xenstat/libxenstat/src/xenstat.c b/tools/xenstat/libxenstat/src/xenstat.c index 85ffc0872d..52f3e6741b 100644 --- a/tools/xenstat/libxenstat/src/xenstat.c +++ b/tools/xenstat/libxenstat/src/xenstat.c @@ -22,6 +22,7 @@ #include #include #include "xenstat.h" +#include "version.h" /* * Types @@ -32,6 +33,9 @@ struct xenstat_handle { FILE *procnetdev; }; +#define SHORT_ASC_LEN 5 /* length of 65535 */ +#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1) + struct xenstat_node { unsigned int flags; unsigned long long cpu_hz; @@ -39,6 +43,7 @@ struct xenstat_node { unsigned long long tot_mem; unsigned long long free_mem; unsigned int num_domains; + char xen_version[VERSION_SIZE]; /* xen version running on this node */ xenstat_domain *domains; /* Array of length num_domains */ }; @@ -47,7 +52,7 @@ struct xenstat_domain { unsigned int state; unsigned long long cpu_ns; unsigned int num_vcpus; - xenstat_vcpu *vcpus; /* Array of length num_vcpus */ + xenstat_vcpu *vcpus; /* Array of length num_vcpus */ unsigned long long cur_mem; /* Current memory reservation */ unsigned long long max_mem; /* Total memory allowed */ unsigned int ssid; @@ -164,6 +169,8 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) #define DOMAIN_CHUNK_SIZE 256 xenstat_node *node; dom0_physinfo_t physinfo; + xen_extraversion_t version; + long vnum = 0; dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE]; unsigned int num_domains, new_domains; unsigned int i; @@ -179,6 +186,14 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) return NULL; } + /* Get the xen version number and xen version tag */ + if (xi_get_xen_version(handle->xihandle, &vnum, &version) < 0) { + free(node); + return NULL; + } + snprintf(node->xen_version, VERSION_SIZE, + "%ld.%ld%s\n", ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, (char *)version); + node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL; node->num_cpus = (physinfo.threads_per_core * physinfo.cores_per_socket * @@ -247,8 +262,8 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) if(collectors[i].collect(handle, node) == 0) { xenstat_free_node(node); return NULL; - } - } + } + } } return node; @@ -291,6 +306,11 @@ xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node, return NULL; } +const char *xenstat_node_xen_ver(xenstat_node * node) +{ + return node->xen_version; +} + unsigned long long xenstat_node_tot_mem(xenstat_node * node) { return node->tot_mem; diff --git a/tools/xenstat/libxenstat/src/xenstat.h b/tools/xenstat/libxenstat/src/xenstat.h index 7542a07d98..2c3617e302 100644 --- a/tools/xenstat/libxenstat/src/xenstat.h +++ b/tools/xenstat/libxenstat/src/xenstat.h @@ -51,6 +51,8 @@ xenstat_domain *xenstat_node_domain(xenstat_node * node, /* Get the domain with the given index; used to loop over all domains. */ xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node, unsigned index); +/* Get xen version of the node */ +const char *xenstat_node_xen_ver(xenstat_node * node); /* Get amount of total memory on a node */ unsigned long long xenstat_node_tot_mem(xenstat_node * node); -- 2.30.2